home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_016 / source.files / ilbmr.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  5KB  |  148 lines

  1. /*----------------------------------------------------------------------*
  2.  * ILBMR.C  Support routines for reading ILBM files.           11/27/85
  3.  * (IFF is Interchange Format File.)
  4.  *
  5.  * By Jerry Morrison and Steve Shaw, Electronic Arts.
  6.  * This software is in the public domain.
  7.  *
  8.  * This version for the Commodore-Amiga computer.
  9.  *----------------------------------------------------------------------*/
  10. #include "iff/packer.h"
  11. #include "iff/ilbm.h"
  12.  
  13.  
  14. /* ---------- GetCMAP ------------------------------------------------*/
  15. /* pNColorRegs is passed in as a pointer to the number of ColorRegisters
  16.  * caller has space to hold.  GetCMAP sets to the number actually read.*/
  17. IFFP GetCMAP(ilbmContext, colorMap, pNColorRegs)   
  18.       GroupContext *ilbmContext;  WORD *colorMap;  UBYTE *pNColorRegs;
  19.    {
  20.    register int nColorRegs;   
  21.    register IFFP iffp;
  22.    ColorRegister colorReg;
  23.  
  24.    nColorRegs = ilbmContext->ckHdr.ckSize / sizeofColorRegister;
  25.    if (*pNColorRegs < nColorRegs)   nColorRegs = *pNColorRegs;
  26.    *pNColorRegs = nColorRegs;    /* Set to the number actually there.*/
  27.  
  28.    for ( ;  nColorRegs > 0;  --nColorRegs)  {
  29.       iffp = IFFReadBytes(ilbmContext, (BYTE *)&colorReg,sizeofColorRegister);
  30.       CheckIFFP();
  31.       *colorMap++ = ( ( colorReg.red   >> 4 ) << 8 ) |
  32.             ( ( colorReg.green >> 4 ) << 4 ) |
  33.             ( ( colorReg.blue  >> 4 )      );
  34.       }
  35.    return(IFF_OKAY);
  36.    }
  37.  
  38. /*---------- GetBODY ---------------------------------------------------*/
  39. /* NOTE: This implementation could be a LOT faster if it used more of the
  40.  * supplied buffer. It would make far fewer calls to IFFReadBytes (and
  41.  * therefore to DOS Read) and to movemem. */
  42. IFFP GetBODY(context, bitmap, mask, bmHdr, buffer, bufsize)
  43.       GroupContext *context;  struct BitMap *bitmap;  BYTE *mask;
  44.       BitMapHeader *bmHdr;  BYTE *buffer;  LONG bufsize;
  45.    {
  46.    register IFFP iffp;
  47.    UBYTE srcPlaneCnt = bmHdr->nPlanes;   /* Haven't counted for mask plane yet*/
  48.    WORD srcRowBytes = RowBytes(bmHdr->w);
  49.    LONG bufRowBytes = MaxPackedSize(srcRowBytes);
  50.    int nRows = bmHdr->h;
  51.    Compression compression = bmHdr->compression;
  52.    register int iPlane, iRow, nEmpty;
  53.    register WORD nFilled;
  54.    BYTE *buf, *nullDest, *nullBuf, **pDest;
  55.    BYTE *planes[MaxSrcPlanes]; /* array of ptrs to planes & mask */
  56.  
  57.    if (compression > cmpByteRun1)
  58.       return(CLIENT_ERROR);
  59.  
  60.    /* Complain if client asked for a conversion GetBODY doesn't handle.*/
  61.    if ( srcRowBytes  !=  bitmap->BytesPerRow  ||
  62.          bufsize < bufRowBytes * 2  ||
  63.          srcPlaneCnt > MaxSrcPlanes )
  64.       return(CLIENT_ERROR);
  65.  
  66.    if (nRows > bitmap->Rows)
  67.       nRows = bitmap->Rows;
  68.    
  69.    /* Initialize array "planes" with bitmap ptrs; NULL in empty slots.*/
  70.    for (iPlane = 0; iPlane < bitmap->Depth; iPlane++)
  71.       planes[iPlane] = (BYTE *)bitmap->Planes[iPlane];
  72.    for ( ;  iPlane < MaxSrcPlanes;  iPlane++)
  73.       planes[iPlane] = NULL;
  74.  
  75.    /* Copy any mask plane ptr into corresponding "planes" slot.*/
  76.    if (bmHdr->masking == mskHasMask) {
  77.       if (mask != NULL)
  78.          planes[srcPlaneCnt] = mask;  /* If there are more srcPlanes than
  79.                * dstPlanes, there will be NULL plane-pointers before this.*/
  80.       else
  81.          planes[srcPlaneCnt] = NULL;  /* In case more dstPlanes than src.*/
  82.       srcPlaneCnt += 1;  /* Include mask plane in count.*/
  83.       }
  84.  
  85.    /* Setup a sink for dummy destination of rows from unwanted planes.*/
  86.    nullDest = buffer;
  87.    buffer  += srcRowBytes;
  88.    bufsize -= srcRowBytes;
  89.  
  90.    /* Read the BODY contents into client's bitmap.
  91.     * De-interleave planes and decompress rows.
  92.     * MODIFIES: Last iteration modifies bufsize.*/
  93.    buf = buffer + bufsize;  /* Buffer is currently empty.*/
  94.    for (iRow = nRows; iRow > 0; iRow--)  {
  95.       for (iPlane = 0; iPlane < srcPlaneCnt; iPlane++)  {
  96.  
  97.          pDest = &planes[iPlane];
  98.  
  99.          /* Establish a sink for any unwanted plane.*/
  100.          if (*pDest == NULL) {
  101.         nullBuf = nullDest;
  102.             pDest   = &nullBuf;
  103.             }
  104.  
  105.          /* Read in at least enough bytes to uncompress next row.*/
  106.          nEmpty  = buf - buffer;      /* size of empty part of buffer.*/
  107.          nFilled = bufsize - nEmpty;      /* this part has data.*/
  108.      if (nFilled < bufRowBytes) {
  109.         /* Need to read more.*/
  110.  
  111.         /* Move the existing data to the front of the buffer.*/
  112.         /* Now covers range buffer[0]..buffer[nFilled-1].*/
  113.             movmem(buf, buffer, nFilled);  /* Could be moving 0 bytes.*/
  114.  
  115.             if (nEmpty > ChunkMoreBytes(context)) {
  116.                /* There aren't enough bytes left to fill the buffer.*/
  117.                nEmpty = ChunkMoreBytes(context);
  118.                bufsize = nFilled + nEmpty;  /* heh-heh */
  119.                }
  120.  
  121.         /* Append new data to the existing data.*/
  122.             iffp = IFFReadBytes(context, &buffer[nFilled], nEmpty);
  123.             CheckIFFP();
  124.  
  125.             buf     = buffer;
  126.         nFilled = bufsize;
  127.         nEmpty  = 0;
  128.         }
  129.  
  130.          /* Copy uncompressed row to destination plane.*/
  131.          if (compression == cmpNone) {
  132.             if (nFilled < srcRowBytes)  return(BAD_FORM);
  133.         movmem(buf, *pDest, srcRowBytes);
  134.         buf    += srcRowBytes;
  135.             *pDest += srcRowBytes;
  136.             }
  137.      else
  138.          /* Decompress row to destination plane.*/
  139.             if ( UnPackRow(&buf, pDest, nFilled,  srcRowBytes) )
  140.                     /*  pSource, pDest, srcBytes, dstBytes  */
  141.                return(BAD_FORM);
  142.          }
  143.       }
  144.  
  145.    return(IFF_OKAY);
  146.    }
  147.  
  148.